#ifndef GPDMA_H_
#define GPDMA_H_

/*******************************************************************************
 * File name: 		gpdma.h
 * Description: 
 * Project: 		Gpdma
 * Target: 			LPC2478
 * Compiler: 		arm-none-eabi-gcc
 * Date: 			22-08-2011
 * Author: 			kuba-pc
 * Based on: 		---
 ******************************************************************************/

/*==============================================================================
 Includes
==============================================================================*/
# include "irq.h"
/*==============================================================================
 Defines
==============================================================================*/

/*==============================================================================
 Globals
==============================================================================*/
enum mode {
	gpdmaM2M,													/* memory to memory 			*/
	gpdmaM2P,													/* memory to peripheral 		*/
	gpdmaP2M,													/* peripheral to memory 		*/
	gpdmaP2P														/* peripheral to peripheral 	*/
};

enum sbSize {
	gpdmaSB_SIZE1 		= GPDMA_CH_CTRL_SB_SIZE_1,		/* 1 word 		*/
	gpdmaSB_SIZE4 		= GPDMA_CH_CTRL_SB_SIZE_4,		/* 4 words 		*/
	gpdmaSB_SIZE8 		= GPDMA_CH_CTRL_SB_SIZE_8,		/* 8 words 		*/
	gpdmaSB_SIZE16		= GPDMA_CH_CTRL_SB_SIZE_16,	/* and so on.. 	*/
	gpdmaSB_SIZE32 	= GPDMA_CH_CTRL_SB_SIZE_32,
	gpdmaSB_SIZE64 	= GPDMA_CH_CTRL_SB_SIZE_64,
	gpdmaSB_SIZE128	= GPDMA_CH_CTRL_SB_SIZE_128,
	sgpdmaSB_SIZE256	= GPDMA_CH_CTRL_SB_SIZE_256
};

enum dbSize {
	gpdmaDB_SIZE1 		= GPDMA_CH_CTRL_DB_SIZE_1,		/* 1 word 		*/
	gpdmaDB_SIZE4 		= GPDMA_CH_CTRL_DB_SIZE_4,		/* 4 words 		*/
	gpdmaDB_SIZE8 		= GPDMA_CH_CTRL_DB_SIZE_8,		/* 8 words 		*/
	gpdmaDB_SIZE16		= GPDMA_CH_CTRL_DB_SIZE_16,	/* and so on.. 	*/
	gpdmaDB_SIZE32 	= GPDMA_CH_CTRL_DB_SIZE_32,
	gpdmaDB_SIZE64 	= GPDMA_CH_CTRL_DB_SIZE_64,
	gpdmaDB_SIZE128 	= GPDMA_CH_CTRL_DB_SIZE_128,
	gpdmaDB_SIZE256 	= GPDMA_CH_CTRL_DB_SIZE_256
};

enum sWidth {
	gpdmaS_WIDTH8 	= GPDMA_CH_CTRL_SWIDTH_8,			/* 8 bits 		*/
	gpdmaS_WIDTH16 = GPDMA_CH_CTRL_SWIDTH_16,			/* 16 bits 		*/
	gpdmaS_WIDTH32 = GPDMA_CH_CTRL_SWIDTH_32			/* 32 bits		*/
};

enum dWidth {
	gpdmaD_WIDTH8 	= GPDMA_CH_CTRL_DWIDTH_8,			/* 8 bits 		*/
	gpdmaD_WIDTH16 = GPDMA_CH_CTRL_DWIDTH_16,			/* 16 bits 		*/
	gpdmaD_WIDTH32 = GPDMA_CH_CTRL_DWIDTH_32			/* 32 bits 		*/
};

enum srcPeriph {
	gpdmaSRC_PERIPH_SSP0TX	= GPDMA_CH_CFG_SRC_PERIPH_SSP0TX,
	gpdmaSRC_PERIPH_SSP0RX 	= GPDMA_CH_CFG_SRC_PERIPH_SSP0RX,
	gpdmaSRC_PERIPH_SSP1TX 	= GPDMA_CH_CFG_SRC_PERIPH_SSP1TX,
	gpdmaSRC_PERIPH_SSP1RX 	= GPDMA_CH_CFG_SRC_PERIPH_SSP1RX,
	gpdmaSRC_PERIPH_SD_MMC 	= GPDMA_CH_CFG_SRC_PERIPH_SD,
	gpdmaSRC_PERIPH_I2S0 	= GPDMA_CH_CFG_SRC_PERIPH_I2S0,
	gpdmaSRC_PERIPH_I2S1    = GPDMA_CH_CFG_SRC_PERIPH_I2S1
};

enum dstPeriph {
	gpdmaDST_PERIPH_SSP0TX	= GPDMA_CH_CFG_DST_PERIPH_SSP0TX,
	gpdmaDST_PERIPH_SSP0RX 	= GPDMA_CH_CFG_DST_PERIPH_SSP0RX,
	gpdmaDST_PERIPH_SSP1TX 	= GPDMA_CH_CFG_DST_PERIPH_SSP1TX,
	gpdmaDST_PERIPH_SSP1RX 	= GPDMA_CH_CFG_DST_PERIPH_SSP1RX,
	gpdmaDST_PERIPH_SD_MMC 	= GPDMA_CH_CFG_DST_PERIPH_SD,
	gpdmaDST_PERIPH_I2S0 	= GPDMA_CH_CFG_DST_PERIPH_I2S0,
	gpdmaDST_PERIPH_I2S1    = GPDMA_CH_CFG_DST_PERIPH_I2S1
};

enum flowCtrl {
	gpdmaFLOW_CTRL_M2M_DMA 	= GPDMA_CH_CFG_FLOW_CTRL_M2M_DMA,	/* memory to memory transfer, flow control: DMA */
	gpdmaFLOW_CTRL_M2P_DMA 	= GPDMA_CH_CFG_FLOW_CTRL_M2P_DMA,	/* memory to periph transfer, flow control: DMA */
	gpdmaFLOW_CTRL_P2M_DMA 	= GPDMA_CH_CFG_FLOW_CTRL_P2M_DMA,	/* periph to memory transfer, flow control: DMA */
	gpdmaFLOW_CTRL_P2P_DMA 	= GPDMA_CH_CFG_FLOW_CTRL_SP2DP_DMA,	/* periph to periph transfer, flow control: DMA */
	gpdmaFLOW_CTRL_P2P_DP 	= GPDMA_CH_CFG_FLOW_CTRL_SP2DP_DP,	/* periph to periph transfer, flow control: destination periph */
	gpdmaFLOW_CTRL_M2P_P 	= GPDMA_CH_CFG_FLOW_CTRL_M2P_P,		/* memory to periph transfer, flow control: periph */
	gpdmaFLOW_CTRL_P2M_P 	= GPDMA_CH_CFG_FLOW_CTRL_P2M_P,		/* periph to memory transfer, flow control: periph */
	gpdmaFLOW_CTRL_P2P_SP 	= GPDMA_CH_CFG_FLOW_CTRL_SP2DP_SP	/* periph to periph transfer, flow control: source periph */
};

struct list {
   uint32      srcAddr;                         /* source address */
   uint32      dstAddr;                         /* destination address */
   struct list *next;                           /* pointer to next linked list item */
   uint32      ctrl;                            /* control word */
};

struct gpdmaConf {
   enum mode         mode;                      /* type of transfer */
   enum sWidth       srcWidth;                  /* source word width */
   enum dWidth       dstWidth;                  /* destination word width */
   enum sbSize       sbSize;                    /* source burst size */
   enum dbSize       dbSize;                    /* destination burst size */
   enum srcPeriph    srcPeriph;                 /* source peripheral */
   enum dstPeriph    dstPeriph;                 /* destination peripheral */
   enum flowCtrl     flowCtrl;                  /* flow control */
   uint32            srcAddr;                   /* source address */
   uint32            dstAddr;                   /* destination address */
   uint32            listItems;                 /* number of list items */
   uint32            *listSrcAddr;              /* source addresses for list */
   uint32            *listDstAddr;              /* destination addresses for list */
   void              (*transferEndService)(void); /* user service at the end of transfer */
   void              (*errorService)(void);       /* user service in case of error */
};

typedef struct gpdmaChannel *gpdmaChannel;

/*==============================================================================
 Global function prototypes
==============================================================================*/
/*------------------------------------------------------------------------------
 function name:   gpdmaInit
 description:     GPDMA module initialization
 parameters:      interrupt priority
 returned value:  none
------------------------------------------------------------------------------*/
bool gpdmaInit             (enum priority priority);

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl0Init
 description:     channel 0 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl0Init   (const struct gpdmaConf *gpdmaConf);

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl1Init
 description:     channel 1 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl1Init   (const struct gpdmaConf *gpdmaConf);

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl0Enable
 description:     enable channel 0
 parameters:      channel settings, size
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl0Enable      (const gpdmaChannel gpdmaChnl, const uint16 size);

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl1Enable
 description:     enable channel 1
 parameters:      channel settings, size
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl1Enable      (const gpdmaChannel gpdmaChnl, const uint16 size);

/******************************************************************************
* END OF FILE
******************************************************************************/

#endif /* GPDMA_H_ */
